﻿using System;
using System.IO;
using System.Linq;
using System.Xml.Linq;

public class XsdRecursiveSorter
{
    // 新增文件夹处理功能
    public void ProcessDirectory(string inputDir, string outputDir)
    {
        var files = Directory.GetFiles(inputDir, "*.xsd", SearchOption.AllDirectories);

        foreach (var inputFile in files)
        {
            try
            {
                var relativePath = GetRelativePath(inputDir, inputFile);
                var fileName = Path.GetFileNameWithoutExtension(relativePath) + "_sorted" + Path.GetExtension(relativePath);
                var outputFile = Path.Combine(outputDir, Path.GetDirectoryName(relativePath), fileName);

                Directory.CreateDirectory(Path.GetDirectoryName(outputFile));
                SortXsdRecursive(inputFile, outputFile);
            } 
            catch (Exception ex)
            {
                Console.WriteLine($"Error processing {inputFile}: {ex.Message}");
            }
        }
    }
    // 新增兼容方法
    private static string GetRelativePath(string basePath, string fullPath)
    {
        var baseUri = new Uri(basePath.EndsWith(Path.DirectorySeparatorChar.ToString())
            ? basePath
            : basePath + Path.DirectorySeparatorChar);

        var fullUri = new Uri(fullPath);

        if (baseUri.Scheme != fullUri.Scheme)
            return fullPath;

        var relativeUri = baseUri.MakeRelativeUri(fullUri);
        return Uri.UnescapeDataString(relativeUri.ToString())
            .Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
    }
    public void SortXsdRecursive(string inputPath, string outputPath)
    {
        var doc = XDocument.Load(inputPath);
        ProcessComplexTypes(doc.Root);
        doc.Save(outputPath);
    }

    private void ProcessComplexTypes(XElement element)
    {
        foreach (var ct in element.Elements().Where(e => e.Name.LocalName == "complexType" || e.Name.LocalName == "simpleType"))
        {
            SortContainerElements(ct);
            //ProcessComplexTypes(ct); // 递归处理嵌套complexType
            ProcessChildComplexTypes(ct); // 递归处理当前complexType内的所有子complexType
        }
    }
    // 新增方法：处理嵌套的complexType
    private void ProcessChildComplexTypes(XElement parentElement)
    {
        foreach (var element in parentElement.Descendants()
                 .Where(e => e.Name.LocalName == "element" &&
                      e.Elements().Any(c => c.Name.LocalName == "complexType" )))
        {
            var childComplexType = element.Element(XName.Get("complexType", parentElement.GetNamespaceOfPrefix("xs").NamespaceName));
            if (childComplexType != null)
            {
                SortContainerByNestedPriority(childComplexType);
                ProcessChildComplexTypes(childComplexType); // 继续递归处理
            }
        }
    }

    private void SortContainerByNestedPriority1(XElement parent)
    {
        // 处理同级元素排序
        var orderedNodes = parent.Nodes()
            .Select((n, i) => new { Node = n, Index = i })
            .OrderBy(x => {
                 if (!(x.Node is XElement e)) return 2;

                 // 替换switch表达式为传统switch语句
                 switch (e.Name.LocalName)
                 {
                     case "complexType":
                         return 1;
                     case "simpleType":
                         return 3;
                     default:
                         return 2;
                 }
             })
            .ThenBy(x => (x.Node as XElement)?.Attribute("name")?.Value ?? "")
            .Select(x => x.Node);

        parent.ReplaceNodes(orderedNodes);

        // 递归处理complexType
        foreach (var complexType in parent.Elements("complexType"))
        {
            var containers = complexType.Elements()
                .Where(e => e.Name.LocalName == "all" || e.Name.LocalName == "sequence");

            foreach (var container in containers)
            {
                var elements = container.Elements()
                    .Where(e => e.Name.LocalName == "element")
                    .OrderBy(e => HasNestedType(e) ? 1 : 0)
                    .ThenBy(e => e.Attribute("name")?.Value, StringComparer.OrdinalIgnoreCase)
                    .ToList();

                container.ReplaceNodes(elements);
                SortContainerByNestedPriority(container); // 递归排序嵌套结构
            }
        }

        // 处理simpleType排序
        var simpleTypes = parent.Elements("simpleType")
            .OrderBy(e => e.Attribute("name")?.Value)
            .ToList();

        if (simpleTypes.Any())
        {
            parent.ReplaceNodes(
                parent.Elements().Where(e => e.Name.LocalName != "simpleType")
                    .Concat(simpleTypes)
            );
        }
    }
    // 修改后的排序逻辑（保持原有规则）
    private void SortContainerByNestedPriority(XElement complexType)
    {
        var containers = complexType.Elements()
            .Where(e => e.Name.LocalName == "all" || e.Name.LocalName == "sequence");

        foreach (var container in containers)
        {
            var elements = container.Elements()
                .Where(e => e.Name.LocalName == "element")
                .OrderBy(e => HasNestedComplexType(e) ? 1 : 0)
                .ThenBy(e => e.Attribute("name")?.Value, StringComparer.OrdinalIgnoreCase)
                .ToList();

            var otherNodes = container.Nodes()
                .Where(n => !(n is XElement e && e.Name.LocalName == "element"));

            container.ReplaceNodes(otherNodes.Concat(elements));
        }
    }
    private void SortContainerBySimplePriority(XElement simpleType)
    {
        var containers = simpleType.Elements();

        foreach (var container in containers)
        {
            var elements = container.Elements()
                .Where(e => e.Name.LocalName == "element")
                .OrderBy(e => HasNestedType(e) ? 1 : 0)
                .ThenBy(e => e.Attribute("name")?.Value, StringComparer.OrdinalIgnoreCase)
                .ToList();

            var otherNodes = container.Nodes()
                .Where(n => !(n is XElement e && e.Name.LocalName == "element"));

            container.ReplaceNodes(otherNodes.Concat(elements));
        }
    }
    private void SortContainerElements(XElement complexType)
    {
        var containers = complexType.Elements()
            .Where(e => e.Name.LocalName == "all" || e.Name.LocalName == "sequence");

        foreach (var container in containers)
        {
            var elements = container.Elements()
               .Where(e => e.Name.LocalName == "element")
               .OrderBy(e => HasNestedComplexType(e) ? 1 : 0) // 有嵌套的排后面
               .ThenBy(e => e.Attribute("name")?.Value, StringComparer.OrdinalIgnoreCase)
               .ToList();

            // 保持非element节点原样（annotation等）
            var otherNodes = container.Nodes()
                .Where(n => !(n is XElement e && e.Name.LocalName == "element"));

            container.ReplaceNodes(otherNodes.Concat(elements));
        }
    }
    private bool HasNestedComplexType(XElement element)
    {
        return element.Descendants()
            .Any(e => e.Name.LocalName == "complexType");
    }
    private bool HasNestedType(XElement element)
    {
        return element.Elements().Any(e => e.Name.LocalName == "complexType"||
            e.Name.LocalName == "simpleType");
    }
}

